package handlers

import (
	"domain-system/models"
	"domain-system/services"
	"errors"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// PostHandler 帖子处理器
type PostHandler struct {
	postService *services.PostService
	db          *gorm.DB // 添加数据库访问
}

// NewPostHandler 创建帖子处理器实例
func NewPostHandler(db *gorm.DB) *PostHandler {
	return &PostHandler{
		postService: services.NewPostService(db),
		db:          db, // 设置数据库连接
	}
}

// CreatePost 创建帖子
func (h *PostHandler) CreatePost(c *gin.Context) {
	var req services.CreatePostRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	// 从JWT中获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": "未授权访问",
		})
		return
	}
	req.UserID = userID.(string)

	post, err := h.postService.CreatePost(&req)
	if err != nil {
		// 根据错误类型返回不同的HTTP状态码
		switch err {
		case services.ErrPaymentRequired:
			c.JSON(http.StatusPaymentRequired, gin.H{
				"error": "需要完成支付才能发布帖子",
				"code":  "PAYMENT_REQUIRED",
			})
		case services.ErrPaymentNotFound:
			c.JSON(http.StatusBadRequest, gin.H{
				"error": "支付记录不存在",
				"code":  "PAYMENT_NOT_FOUND",
			})
		default:
			c.JSON(http.StatusInternalServerError, gin.H{
				"error": "创建帖子失败: " + err.Error(),
			})
		}
		return
	}

	c.JSON(http.StatusCreated, successResponse(post))
}

// GetPost 获取帖子详情
func (h *PostHandler) GetPost(c *gin.Context) {
	postIDStr := c.Param("id")
	postID, err := strconv.ParseUint(postIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的帖子ID", ""))
		return
	}

	// 获取查看者ID
	viewerID := ""
	if userID, exists := c.Get("user_id"); exists {
		viewerID = userID.(string)
	}

	post, err := h.postService.GetPostByID(uint(postID), viewerID)
	if err != nil {
		c.JSON(http.StatusNotFound, errorResponse(404, "获取帖子失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"data": post,
	}))
}

// GetPostsByCircle 获取圈子帖子列表
func (h *PostHandler) GetPostsByCircle(c *gin.Context) {
	circleIDStr := c.Param("circle_id")
	circleID, err := strconv.ParseUint(circleIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的圈子ID", ""))
		return
	}

	// 构建查询参数
	req := &services.PostListRequest{
		CircleID:  func() *uint { id := uint(circleID); return &id }(),
		Page:      1,
		PageSize:  20,
		SortBy:    "created_at",
		SortOrder: "desc",
	}

	// 从查询参数获取分页信息
	if pageStr := c.Query("page"); pageStr != "" {
		if page, err := strconv.Atoi(pageStr); err == nil && page > 0 {
			req.Page = page
		}
	}
	if pageSizeStr := c.Query("page_size"); pageSizeStr != "" {
		if pageSize, err := strconv.Atoi(pageSizeStr); err == nil && pageSize > 0 && pageSize <= 100 {
			req.PageSize = pageSize
		}
	}

	// 获取查看者ID
	viewerID := ""
	if userID, exists := c.Get("user_id"); exists {
		viewerID = userID.(string)
	}

	posts, total, err := h.postService.GetPostList(req, viewerID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, errorResponse(500, "获取帖子列表失败", err.Error()))
		return
	}

	// 使用统一的ApiResp格式
	c.JSON(http.StatusOK, successResponse(gin.H{
		"posts":     posts,
		"total":     total,
		"page":      req.Page,
		"page_size": req.PageSize,
	}))
}

// UpdatePost 更新帖子
func (h *PostHandler) UpdatePost(c *gin.Context) {
	postIDStr := c.Param("id")
	postID, err := strconv.ParseUint(postIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的帖子ID", ""))
		return
	}

	// 获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, errorResponse(401, "未授权访问", ""))
		return
	}

	var req services.UpdatePostRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "参数错误", err.Error()))
		return
	}

	post, err := h.postService.UpdatePost(uint(postID), userID.(string), &req)
	if err != nil {
		if errors.Is(err, services.ErrUnauthorizedPost) {
			c.JSON(http.StatusForbidden, errorResponse(403, "权限不足", err.Error()))
			return
		}
		if errors.Is(err, services.ErrPostNotFound) {
			c.JSON(http.StatusNotFound, errorResponse(404, "资源不存在", err.Error()))
			return
		}
		// 其他错误返回400
		c.JSON(http.StatusBadRequest, errorResponse(400, "更新帖子失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"message": "帖子更新成功",
		"data":    post,
	}))
}

// DeletePost 删除帖子
func (h *PostHandler) DeletePost(c *gin.Context) {
	postIDStr := c.Param("id")
	postID, err := strconv.ParseUint(postIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的帖子ID", ""))
		return
	}

	// 获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, errorResponse(401, "未授权访问", ""))
		return
	}

	err = h.postService.DeletePost(uint(postID), userID.(string))
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "删除帖子失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"message": "帖子删除成功",
	}))
}

// LikePost 点赞帖子
func (h *PostHandler) LikePost(c *gin.Context) {
	postIDStr := c.Param("id")
	postID, err := strconv.ParseUint(postIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的帖子ID", ""))
		return
	}

	// 获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, errorResponse(401, "未授权访问", ""))
		return
	}

	err = h.postService.LikePost(uint(postID), userID.(string))
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "点赞失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"message": "点赞成功",
	}))
}

// UnlikePost 取消点赞帖子
func (h *PostHandler) UnlikePost(c *gin.Context) {
	postIDStr := c.Param("id")
	postID, err := strconv.ParseUint(postIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的帖子ID", ""))
		return
	}

	// 获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, errorResponse(401, "未授权访问", ""))
		return
	}

	err = h.postService.UnlikePost(uint(postID), userID.(string))
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "取消点赞失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"message": "取消点赞成功",
	}))
}

// GetPostComments 获取帖子评论列表
func (h *PostHandler) GetPostComments(c *gin.Context) {
	postIDStr := c.Param("id")
	postID, err := strconv.ParseUint(postIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的帖子ID", ""))
		return
	}

	// 获取分页参数
	page := 1
	pageSize := 20
	if pageStr := c.Query("page"); pageStr != "" {
		if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
			page = p
		}
	}
	if pageSizeStr := c.Query("page_size"); pageSizeStr != "" {
		if ps, err := strconv.Atoi(pageSizeStr); err == nil && ps > 0 && ps <= 100 {
			pageSize = ps
		}
	}

	comments, total, err := h.postService.GetPostComments(uint(postID), page, pageSize)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "获取评论失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"comments":  comments,
		"total":     total,
		"page":      page,
		"page_size": pageSize,
	}))
}

// CreateComment 创建评论
func (h *PostHandler) CreateComment(c *gin.Context) {
	postIDStr := c.Param("id")
	postID, err := strconv.ParseUint(postIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的帖子ID", ""))
		return
	}

	// 获取用户ID
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, errorResponse(401, "未授权访问", ""))
		return
	}

	// 定义用于JSON绑定的结构体
	var reqBody struct {
		Content  string `json:"content" binding:"required"`
		ParentID *uint  `json:"parent_id,omitempty"`
	}

	if err := c.ShouldBindJSON(&reqBody); err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "参数错误", err.Error()))
		return
	}

	// 构建完整的请求结构体
	req := services.CommentRequest{
		PostID:   uint(postID),
		UserID:   userID.(string),
		Content:  reqBody.Content,
		ParentID: reqBody.ParentID,
	}

	comment, err := h.postService.CreateComment(&req)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "创建评论失败", err.Error()))
		return
	}

	c.JSON(http.StatusCreated, successResponse(gin.H{
		"message": "评论创建成功",
		"data":    comment,
	}))
}

// GetCircles 获取圈子列表
func (h *PostHandler) GetCircles(c *gin.Context) {
	// 获取查询参数
	circleType := c.Query("type")
	country := c.Query("country")
	city := c.Query("city")

	// 构建查询
	query := h.db.Model(&models.Circle{}).Where("is_active = ?", true)

	if circleType != "" {
		query = query.Where("type = ?", circleType)
	}
	if country != "" {
		query = query.Where("country_code = ?", country)
	}
	if city != "" {
		query = query.Where("city_code = ?", city)
	}

	var circles []models.Circle
	if err := query.Order("created_at DESC").Find(&circles).Error; err != nil {
		c.JSON(http.StatusInternalServerError, errorResponse(500, "获取圈子列表失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"data": circles,
	}))
}

// GetTags 获取标签列表
func (h *PostHandler) GetTags(c *gin.Context) {
	var tags []models.Tag
	if err := h.db.Where("is_active = ?", true).Order("post_count DESC").Find(&tags).Error; err != nil {
		c.JSON(http.StatusInternalServerError, errorResponse(500, "获取标签列表失败", err.Error()))
		return
	}
	// 转换为客户端期望的格式
	tagsResponse := make([]map[string]interface{}, len(tags))
	for i, tag := range tags {
		tagsResponse[i] = map[string]interface{}{
			"id":        tag.ID,
			"name":      tag.Name,
			"circle_id": tag.CircleID,
			"color":     tag.Color,
		}
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"message": "获取标签成功",
		"data":    tagsResponse,
	}))

}

// GetPostsByTag 根据标签获取帖子列表
func (h *PostHandler) GetPostsByTag(c *gin.Context) {
	tagIDStr := c.Param("tag_id")
	tagID, err := strconv.ParseUint(tagIDStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "无效的标签ID", ""))
		return
	}

	// 构建查询参数
	req := &services.PostListRequest{
		TagID:     func() *uint { id := uint(tagID); return &id }(),
		Page:      1,
		PageSize:  20,
		SortBy:    "created_at",
		SortOrder: "desc",
	}

	// 从查询参数获取分页信息
	if pageStr := c.Query("page"); pageStr != "" {
		if page, err := strconv.Atoi(pageStr); err == nil && page > 0 {
			req.Page = page
		}
	}
	if pageSizeStr := c.Query("page_size"); pageSizeStr != "" {
		if pageSize, err := strconv.Atoi(pageSizeStr); err == nil && pageSize > 0 && pageSize <= 100 {
			req.PageSize = pageSize
		}
	}

	// 获取查看者ID
	viewerID := ""
	if userID, exists := c.Get("user_id"); exists {
		viewerID = userID.(string)
	}

	posts, total, err := h.postService.GetPostList(req, viewerID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, errorResponse(500, "获取帖子列表失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"posts":     posts,
		"total":     total,
		"page":      req.Page,
		"page_size": req.PageSize,
	}))
}

// GetUserPosts 获取用户帖子列表
func (h *PostHandler) GetUserPosts(c *gin.Context) {
	userID := c.Param("user_id")

	// 构建查询参数
	req := &services.PostListRequest{
		UserID:    &userID,
		Page:      1,
		PageSize:  20,
		SortBy:    "created_at",
		SortOrder: "desc",
	}

	// 从查询参数获取分页信息
	if pageStr := c.Query("page"); pageStr != "" {
		if page, err := strconv.Atoi(pageStr); err == nil && page > 0 {
			req.Page = page
		}
	}
	if pageSizeStr := c.Query("page_size"); pageSizeStr != "" {
		if pageSize, err := strconv.Atoi(pageSizeStr); err == nil && pageSize > 0 && pageSize <= 100 {
			req.PageSize = pageSize
		}
	}

	// 获取查看者ID
	viewerID := ""
	if currentUserID, exists := c.Get("user_id"); exists {
		viewerID = currentUserID.(string)
	}

	posts, total, err := h.postService.GetPostList(req, viewerID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, errorResponse(500, "获取用户帖子失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"posts":     posts,
		"total":     total,
		"page":      req.Page,
		"page_size": req.PageSize,
	}))
}

// FollowUser 关注用户
func (h *PostHandler) FollowUser(c *gin.Context) {
	followingID := c.Param("user_id")

	// 获取当前用户ID
	followerID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, errorResponse(401, "未授权访问", ""))
		return
	}

	// 不能关注自己
	if followerID.(string) == followingID {
		c.JSON(http.StatusBadRequest, errorResponse(400, "不能关注自己", ""))
		return
	}

	// 检查是否已经关注
	var existingFollow models.Follow
	if err := h.db.Where("follower_id = ? AND following_id = ?", followerID.(string), followingID).First(&existingFollow).Error; err == nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "已经关注过了", ""))
		return
	}

	// 创建关注关系
	follow := &models.Follow{
		FollowerID:  followerID.(string),
		FollowingID: followingID,
	}

	if err := h.db.Create(follow).Error; err != nil {
		c.JSON(http.StatusInternalServerError, errorResponse(500, "关注失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"message": "关注成功",
	}))
}

// UnfollowUser 取消关注用户
func (h *PostHandler) UnfollowUser(c *gin.Context) {
	followingID := c.Param("user_id")

	// 获取当前用户ID
	followerID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, errorResponse(401, "未授权访问", ""))
		return
	}

	// 查找关注关系
	var follow models.Follow
	if err := h.db.Where("follower_id = ? AND following_id = ?", followerID.(string), followingID).First(&follow).Error; err != nil {
		c.JSON(http.StatusBadRequest, errorResponse(400, "未找到关注关系", ""))
		return
	}

	// 删除关注关系
	if err := h.db.Delete(&follow).Error; err != nil {
		c.JSON(http.StatusInternalServerError, errorResponse(500, "取消关注失败", err.Error()))
		return
	}

	c.JSON(http.StatusOK, successResponse(gin.H{
		"message": "取消关注成功",
	}))
}

// GetGlobalPosts 获取全球圈帖子
func (h *PostHandler) GetGlobalPosts(c *gin.Context) {
	// 查找全球圈
	var globalCircle models.Circle
	if err := h.db.Where("type = ?", models.CircleTypeGlobal).First(&globalCircle).Error; err != nil {
		c.JSON(http.StatusNotFound, errorResponse(404, "全球圈不存在", ""))
		return
	}

	// 重定向到圈子帖子接口
	c.Params = append(c.Params, gin.Param{Key: "circle_id", Value: strconv.Itoa(int(globalCircle.ID))})
	h.GetPostsByCircle(c)
}

// GetCountryPosts 获取国家圈帖子
func (h *PostHandler) GetCountryPosts(c *gin.Context) {
	countryCode := c.Param("country")

	// 查找国家圈
	var countryCircle models.Circle
	if err := h.db.Where("type = ? AND country_code = ?", models.CircleTypeCountry, countryCode).First(&countryCircle).Error; err != nil {
		c.JSON(http.StatusNotFound, errorResponse(404, "国家圈不存在", ""))
		return
	}

	// 重定向到圈子帖子接口
	c.Params = append(c.Params, gin.Param{Key: "circle_id", Value: strconv.Itoa(int(countryCircle.ID))})
	h.GetPostsByCircle(c)
}

// GetCityPosts 获取城市圈帖子
func (h *PostHandler) GetCityPosts(c *gin.Context) {
	cityCode := c.Param("city")

	// 查找城市圈
	var cityCircle models.Circle
	if err := h.db.Where("type = ? AND city_code = ?", models.CircleTypeCity, cityCode).First(&cityCircle).Error; err != nil {
		c.JSON(http.StatusNotFound, errorResponse(404, "城市圈不存在", ""))
		return
	}

	// 重定向到圈子帖子接口
	c.Params = append(c.Params, gin.Param{Key: "circle_id", Value: strconv.Itoa(int(cityCircle.ID))})
	h.GetPostsByCircle(c)
}
